package com.xiyun.easyapi.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.github.jsonzou.jmockdata.JMockData;
import com.xiyun.EasyApiApplication;
import com.xiyun.easyapi.annotation.CustomLog;
import com.xiyun.easyapi.config.util.Current;
import com.xiyun.easyapi.config.util.JwtUtil;
import com.xiyun.easyapi.config.util.Log;
import com.xiyun.easyapi.config.util.Res;
import com.xiyun.easyapi.config.web.CustomException;
import com.xiyun.easyapi.controller.request.PermissionReq;
import com.xiyun.easyapi.model.Permission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;


import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

import static com.xiyun.EasyApiApplication.TEMP_PATH;


/**
 * 任务调度服务
 */
@Service
@CustomLog
public class TaskService {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private PermissionService permissionService;
    @Value("${server.port}")
    private String port;

    public Res<?> deleteTempFile() {
        if (!Current.getUser().getAdmin()) throw new CustomException("任务调度权限不足");
        //遍历临时文件夹
        File file = new File(TEMP_PATH);
        if (!file.exists()) return Res.success();
        Stream.of(Objects.requireNonNull(file.listFiles()))
                .forEach(f -> {
                    //判断是否是文件夹
                    if (f.isDirectory()) {
                        //根据文件名作为时间戳判断是否超过10分钟
                        if (System.currentTimeMillis() - Long.parseLong(f.getName()) > 10 * 60 * 1000) {
                            //删除文件夹
                            FileUtil.del(f);
                        }
                    }
                });
        return Res.success();
    }

    /**
     * 普通代码mock测试
     *
     * @return .
     */
    public Res<?> autoCodeTest() {
        List<Permission> list = new Permission().where(Permission::getAutoTest).eq(true).and(Permission::getIsLowCode).eq(false).list();
        list.forEach(permission -> {
            String controller = permission.getController();
            String method = permission.getMethod();
            try {
                if (Objects.isNull(controller) || Objects.isNull(method)) return;
                Class<?> clazz = Class.forName(controller);
                Arrays.stream(clazz.getDeclaredMethods())
                        .filter(e -> e.getName()
                                .equals(method))
                        .findFirst()
                        .ifPresent(e -> {
                            Class<?>[] parameterTypes = e.getParameterTypes();
                            if (parameterTypes.length == 0) return;
                            Object param = JMockData.mock(parameterTypes[0]);
                            Object obj = EasyApiApplication.app.getBean(EasyApiApplication.app.getBeanNamesForType(clazz)[0]);
                            Arrays.stream(obj.getClass()
                                            .getDeclaredMethods())
                                    .filter(i -> i.getName()
                                            .equals(method))
                                    .findFirst()
                                    .ifPresent(i -> {
                                        try {
                                            //接口方法存在，调用接口
                                            HttpHeaders requestHeaders = new HttpHeaders();
                                            requestHeaders.set("token", jwtUtil.createJwtStr(1L));
                                            HttpEntity<?> requestEntity = new HttpEntity<>(param, requestHeaders);
                                            Object res = restTemplate.postForObject("http://localhost:" + port + "/" + permission.getUrl(), requestEntity, Object.class);
                                            JSON result = JSONUtil.parse(res);
                                            if (JSONUtil.getByPath(result, "$.code.value")
                                                    .toString()
                                                    .equals("500")) {
                                                permissionService.saveTestResult(new PermissionReq.saveTestResult().setId(permission.getId())
                                                        .setTestResult(false));
                                                throw new CustomException("mock测试未通过");
                                            } else {
                                                Log.info("mock测试通过，controller={},method={},result={}", controller, method, result);
                                                permissionService.saveTestResult(new PermissionReq.saveTestResult().setId(permission.getId())
                                                        .setTestResult(true));
                                            }
                                        } catch (CustomException ex) {
                                            throw ex;
                                        } catch (Exception exx) {
                                            Log.error("mock测试失败，controller={},method={}", controller, method, exx);
                                        }
                                    });
                        });
            } catch (CustomException ex) {
                throw ex;
            } catch (Exception e) {
                Log.error("获取bean失败，controller={},method={}", controller, method, e);
            }
        });
        return Res.success();
    }
}
